package com.opo5.logisticsmanagement.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.opo5.logisticsmanagement.common.AutoTaskUtil;
import com.opo5.logisticsmanagement.common.R;
import com.opo5.logisticsmanagement.dao.AutoTaskDao;
import com.opo5.logisticsmanagement.domain.AutoTask;
import com.opo5.logisticsmanagement.service.AutoTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ScheduledFuture;

/**
* @author lixin
* @description 针对表【tbs_auto_task】的数据库操作Service实现
* @createDate 2022-07-10 08:55:41
*/
@Service
@Slf4j
public class AutoTaskServiceImpl extends ServiceImpl<AutoTaskDao, AutoTask>
    implements AutoTaskService {

    @Autowired
    private AutoTaskDao autoTaskDao;

    @Autowired
    private AutoTaskUtil autoTaskUtil;

    private static Map<String, ScheduledFuture> scheduledFutures = new HashMap<>();

    @Override
    public R getAutoTaskByCondition(String reference, String status, Integer currentPage, Integer pageSize) {
        Page<AutoTask> page = new Page<>(currentPage,pageSize);
        QueryWrapper<AutoTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(reference!=null,"reference",reference);
        queryWrapper.eq(status!=null,"status",status);
        autoTaskDao.selectPage(page,queryWrapper);
        List<AutoTask> autoTasks = page.getRecords();
        return R.success(new R().add("autoTasks",autoTasks).add("total",page.getTotal()).getMap());
    }
    @Override
    public void executeAll(){
        // 查询出所有未执行的任务 isExec=0 && now<execTime
        QueryWrapper<AutoTask> queryWrapper = new QueryWrapper<AutoTask>();
        queryWrapper.eq("status", 1);
        List<AutoTask> tasks = autoTaskDao.selectList(queryWrapper);


        if (tasks.size() != 0) {
            tasks.forEach(task -> {
                /*

                //获取数据库数据
                //获取所有的参数
                String[] strArgs = task.getParam().split(",");
                //获取所有的方法名
                String methodName = task.getMethod();
                //获取所有的参数类型
                String[] classTypes = task.getParamType().split(",");
                
                List<Class<?>> argsTypeList = new ArrayList<>();
                List<Object> argsList = new ArrayList<>();

                for (int i = 0; i < strArgs.length; i++) {
                    String classType = classTypes[i];
                    if (classType.length()>0){
                        if ("string".equalsIgnoreCase(classType)) {
                            classType = "java.lang.String";
                            argsList.add(String.valueOf(strArgs[i]));
                        }else if ("integer".equalsIgnoreCase(classType) || "int".equalsIgnoreCase(classType)) {
                            classType = "java.lang.Integer";
                            argsList.add(Integer.valueOf(strArgs[i]));
                        }else if ("long".equalsIgnoreCase(classType)) {
                            classType = "java.lang.Long";
                            argsList.add(Long.valueOf(strArgs[i]));
                        }else if ("double".equalsIgnoreCase(classType)) {
                            classType = "java.lang.Double";
                            argsList.add(Double.valueOf(strArgs[i]));
                        }else if ("boolean".equalsIgnoreCase(classType)) {
                            classType = "java.lang.Boolean";
                            argsList.add(Boolean.valueOf(strArgs[i]));
                        }
                        try {
                            Class<?> aClass = Class.forName(classType);
                            argsTypeList.add(aClass);
                        } catch (ClassNotFoundException e) {
                            log.error("只支持基本的数据类型以及包装类，非法类型:{}",classType);
                        }
                    }


                }

                // List转为Array，invoke要求
                Object[] args = new Object[argsList.size()];
                Class<?>[] classes = new Class[argsTypeList.size()];
                argsTypeList.toArray(classes);
                argsList.toArray(args);



                // 创建定时任务
                log.info("创建定时任务{}", task.getExpl());
                Runnable runnable = () -> {

                    try {
                        Class<?> aClass = Class.forName(task.getReference());
                        Method method = aClass.getMethod(methodName,classes);
                        if (strArgs.length>0){
                            method.invoke(aClass.newInstance(),args);
                        }else{
                            method.invoke(aClass.newInstance());
                        }

                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                        log.error("定时任务{}执行完毕失败:{}", task, e.getMessage());
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    } catch (InstantiationException e) {
                        throw new RuntimeException(e);
                    }
                };*/
                scheduledFutures.put(task.getId()+"",autoTaskUtil.start(task));
            });
        }
    }

    @Override
    public void execute(Integer id) {
        AutoTask autoTask = autoTaskDao.selectById(id);
        autoTask.setStatus("1");
        autoTaskDao.updateById(autoTask);
        scheduledFutures.put(id+"",autoTaskUtil.start(autoTask));
    }

    @Override
    public void close(Integer id){
        if (!scheduledFutures.isEmpty()) {
            AutoTask autoTask = autoTaskDao.selectById(id);
            autoTask.setStatus("0");
            autoTaskDao.updateById(autoTask);
            scheduledFutures.get(id+"").cancel(true);
        }
    }

    @Override
    public void closeAll(){
        Collection<ScheduledFuture> values = scheduledFutures.values();
        for (ScheduledFuture scheduledFuture : values){
            scheduledFuture.cancel(true);
        }

    }

    @Override
    public R addAutoTask(AutoTask autoTask) {
        int flag = autoTaskDao.insert(autoTask);
        if (flag==1){
            return R.success(null);
        }
        return R.error("添加自动任务失败");
    }

    @Override
    public R editAutoTask(AutoTask autoTask) {
        int flag = autoTaskDao.updateById(autoTask);
        if (flag==1){
            AutoTask autoTask1 = autoTaskDao.selectById(autoTask);
            if (autoTask1.getStatus().equals("1")){
                Integer id = autoTask1.getId();
                close(id);
                execute(id);
            }
            return R.success(null);
        }
        return R.error("修改自动任务失败");
    }

    @Override
    public R delAutoTask(Integer[] ids) {
        List<AutoTask> autoTasks = autoTaskDao.selectBatchIds(Arrays.asList(ids));
        autoTasks.forEach(autoTask -> {
            if (autoTask.getStatus().equals("1")){
                close(autoTask.getId());
            }
        });
        int i = autoTaskDao.deleteBatchIds(Arrays.asList(ids));
        if(i != ids.length){
            return R.error("删除了"+i+"条,"+"失败"+(ids.length-i)+"条");
        }
        return R.success(null);
    }

    @Override
    public R switchAutoTaskById(Integer id) {
        AutoTask autoTask = autoTaskDao.selectById(id);
        String status = autoTask.getStatus();
        if("1".equals(status)){
            autoTask.setStatus("0");
            autoTaskDao.updateById(autoTask);
            close(autoTask.getId());
        }else{
            autoTask.setStatus("1");
            autoTaskDao.updateById(autoTask);
            execute(autoTask.getId());
        }
        return R.success(null);
    }


}




